package com.dream.voter;

import cn.hutool.core.text.AntPathMatcher;
import com.dream.entity.Resource;
import org.springframework.security.access.AccessDecisionVoter;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.FilterInvocation;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * 跟据当前登录用户，获取角色IdList,根据角色IdList查询此用户所拥有的权限，根据权限匹配当前用户是否能够访问接口
 */
@Component
public class RoleBasedVoter implements AccessDecisionVoter<Object> {

    AntPathMatcher matcher = new AntPathMatcher();

    @Override
    public boolean supports(ConfigAttribute attribute) {
        return true;
    }

    @Override
    public boolean supports(Class<?> clazz) {
        return true;
    }

    @Override
    public int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) {
        if ("permitAll".equals(attributes.toArray()[0].toString()))
            return ACCESS_GRANTED;
        HttpServletRequest request = ((FilterInvocation) object).getHttpRequest();

        //获取当前用户的权限，当前用户的权限可以存角色IdList,并且根据角色IdList查询所对应的权限，比如数据库配置权限是接口uri,不同角色访问不同接口
        for (GrantedAuthority ga : authentication.getAuthorities()) {
            if (matcher.match(request.getRequestURI(), "/login")) {
                return ACCESS_GRANTED;
            }
            //1. 根据角色Id查询权限及所有公共权限

            //2. 根据request.getRequestURI()进行匹配，匹配成功后放行
            List<Resource> resources= new ArrayList<>();
            if (resources.stream().anyMatch(r -> {
                return matcher.match(r.getUrl(), request.getRequestURI())
                        && (r.getMethod().equalsIgnoreCase(request.getMethod()));
            })) {
                return ACCESS_GRANTED;
            }
        }
        return ACCESS_DENIED;
    }
}
